<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAGx8QhvfhyzKINUFGZHU-TRTRERdeAiwZ9EeJWta3L_JZVS0bOBQLHamJfgwNJ_pgXfBeZWiv6fostw" type="text/javascript"></script>

		<link rel="stylesheet" type="text/css" media="screen" href="http://proviso.informedsources.com/semperfi/masterstyle.css">

		<!--[if IE]>
			<style type="text/css">
				div#resultspanel p {
					padding-left: 26px !important;
					background-position: 2px 6px !important;
				}
			</style>
		<![endif]-->

		<div id="container">

			<div id="home">
				<div id="searchbox">
					<div id="fuelfilter">
						<p><label for="fueltype">Fuel Type</label><span class="labeldest"><select id="fueltype" onchange="handleKeyUp( this, event );"><option value="">Loading...</option></select></span></p>
						<p><label for="fuelbrand">Brand</label><span class="labeldest"><select id="fuelbrand" onchange="handleKeyUp( this, event );"><option value="">Loading...</option></select></span></p>
					</div>

					<div id="searchparameters">
						<p><label for="address">Address or Postcode</label></p>
						<p>
							<span class="labeldest"><input type="text" type="text" name="address" id="address" onkeyup="handleKeyUp( this, event );"/></span>
							<input type="submit" id="go" value="Search petrol prices" onclick="searchByAddress();"/>
						</p>
					</div>
				</div>

				<div id="searchswitches">
					<p>
						<span id="sortoptions">
							Sort by: <a class="current" href="#" id="sortByPriceLink" onclick="sortByPrice();return false;">Price</a> -
							<a href="#" id="sortByLocationLink" onclick="sortByLocation();return false;">Location</a>
						</span>
						<span id="viewoptions">
						</span>
					</p>
				</div>

				<div id="resultspanel"></div>
			</div>

			<div id="canvas_container" style="display: none;">
				<div id="canvas">

				</div>

				<div id="footer_canvas">
					<p class="note">Due to price volatility, MotorMouth cannot guarantee the accuracy of these prices. A maximum of five locations are shown at any one time.</p>
				</div>
			</div>

			<div id="footer">
				<p class="note">MotorMouth cannot guarantee the accuracy of these prices.</p>
			</div>

		</div>

		<script type="text/javascript">

			// GLOBAL VARIABLES
			var prefs = new _IG_Prefs();
			var serviceUrl = 'http://motormouth.net.au/services/fuelpricingservices.ashx?format=json&partner=23&';
			var servoHash = Array();
			var servoCheapest = 0;

			var loadServos_lat = 0;
			var loadServos_lon = 0;
			var loadServos_fuelbrand;
			var loadServos_fueltype;
			var loadServod_padding;
			var loadServos_maxZoom = 15; // 19 is closest zoom, 1 is furthest
			var loadServos_minZoom = 10; // 19 is closest zoom, 1 is furthest

			var servoSortOrder = 'price';

			var mapObj;

			var servoId; // This value is passed from home view when a servo is clicked.
			var autoOpen; // As above but a work around as if servoId returned false if zero.
			var autoOpened = false; // Ensure autoOpen only runs once

			var tabStyle = 'font-size: 12px; color: #016c96; width: 220px; height: 160;';
			var tabHeadingStyle = 'font-size: 14px; color: #016c96; font-weight: bold;';
			var tabImageStyle = 'margin: 5px;';

			var moveListenerActive = true;

			// INITIALISATION
			function init() {

				setMapViewLink();

				_gel('address').value = prefs.getString('address');
				// Load the fuel types into the first combo - this will cascade to update brand
				loadFuelTypes();

				if( !isHome() ) {
					searchByAddress();
				}

				_IG_AdjustIFrameHeight();

				setDisplayType();

			}

			function setDisplayType()
			{
				var home = _gel('home');
				var canvas = _gel('canvas');

				if(isHome())
				{
					canvas.style.display = 'none';
					home.style.width = 'auto';
				}
				else
				{
					var mapWidth = screen.width - 740;
					if( navigator.userAgent.indexOf( 'MSIE 7' ) >= 0 ) {
						mapWidth = 'auto';
					}

					canvas.style.display = 'block';
					_gel('home').style.position = 'absolute';
					_gel('home').style.top = 0;
					_gel('home').style.left = 0;
					_gel('home').style.width = 300;
					_gel('canvas_container').style.display = 'block';
					_gel('footer').style.display = 'none';

					if( _gel('address').value == '' )
					{
						// Zoom map out to see all of Australia
						displayMap(-29, 135, 4);
						updateMappletLink(-29, 135, 4);
					}
				}
			}

			function isHome()
			{
				return (getViewName() == 'home') ? true : false;
			}

			_IG_RegisterOnloadHandler( init );

			// DATA LOADERS

			function loadFuelTypes() {

				fuelEl = _gel( 'fueltype' );
				fuelEl.disabled = true;

				_IG_FetchContent( serviceUrl + 'op=GetFuels', function(response) {
					updateComboBox( response, 'FuelDescription', 'FuelTypeID', 'fueltype', prefs.getString('fueltype'), false, '' );
					loadFuelBrands();
				});
			}

			function loadFuelBrands() {

				var fueltypeEl = _gel('fueltype');

				var brandEl = _gel('fuelbrand');
				brandEl.disabled = true;

				_IG_FetchContent( serviceUrl + 'op=GetBrands&FuelTypeID=' + fueltypeEl.value, function(response) {
					updateComboBox( response, 'Brand', 'Brand', 'fuelbrand', prefs.getString('fuelbrand'), true, 'Brands' );
				});

			}

			function loadServos( lat, lon, zoom ) {

				var fueltypeEl = _gel('fueltype');
				var fueltype = fueltypeEl.value;

				var brandEl = _gel('fuelbrand');
				var fuelbrand = escape( brandEl.value == '-All Brands-' ? 'All Brands' : brandEl.value );

				if( loadServos_lat != lat || loadServos_lon != lon || loadServos_fueltype != fueltype || loadServos_fuelbrand != fuelbrand || loadServos_zoom != zoom ) {

					// Save current search vars so searches aren't duplicated
					loadServos_lat = lat;
					loadServos_lon = lon;
					loadServos_fueltype = fueltype;
					loadServos_fuelbrand = fuelbrand;
					loadServos_zoom = zoom;
					debugLog( 'Lat: ' + loadServos_lat + ', Lon: ' + loadServos_lon + ', Fuel: ' + loadServos_fueltype + ', Brand: ' + loadServos_fuelbrand + ', Zoom: ' + loadServos_zoom );

					// If first search
					if( zoom == 0 ) {
						_gel('resultspanel').innerHTML = '<p>Loading...</p>';
						_IG_AdjustIFrameHeight();
					}

					// add zoom to lookup ( zoom = 19 (clostest) -> 1 (furthest) )
					debugLog( 'Zoom: ' + zoom + ', Pad Power: ' + ( 20 - zoom ) );
					var hpad = ( 0.00174611807 / 2 ) * Math.pow( 2, 20 - zoom );
					var vpad = ( 0.000889762265 / 2 ) * Math.pow( 2, 20 - zoom );

					search_left = lon - hpad;
					search_right = lon + hpad;
					search_top = lat + vpad;
					search_bottom = lat - vpad;

						debugLog( "Searching hpad: " + hpad + ", vpad: " + vpad );
						_IG_FetchContent( serviceUrl + 'op=BrandGeocodeSearch&Brand=' + fuelbrand + '&FuelType=' + fueltype + '&TopLatitude=' + search_top + '&LeftLongitude=' + search_left + '&BottomLatitude=' + search_bottom + '&RightLongitude=' + search_right, function( response ) {

						debugLog( 'Received result from MotorMouth' );

						// Errors?
						if( response == '' ) {
							debugLog( 'blank response' );
							return false;
						}

						if( response.length > 90000 ) {
							_gel('resultspanel').innerHTML = '<p>Too many results found. Please zoom in or refine your search criteria.</p>';
							_IG_AdjustIFrameHeight();
							return false;
						}

						var servos;
						eval( 'servos = ' + response );

						// No results?
						if( servos.ResultData.ResultCode != '0' || ( servos.ResultData.Data && servos.ResultData.Data.length == 0 ) ) {
							if( zoom == loadServos_minZoom ) {
								_gel('resultspanel').innerHTML = '<p>No results found.</p>';
								_IG_AdjustIFrameHeight();
								return false;
							}
							debugLog( 'Calling loadServos( ' + lat + ', ' + lon + ', ' + (zoom-1) + ' ) due to no result' );
							loadServos( lat, lon, zoom-1 );
							return;
						}

						debugLog( "Got " + servos.ResultData.Data.length + " servos" );

						// Less than desired number of results and not searching max area yet?
						if( servos.ResultData.Data.length < 1 && zoom > loadServos_minZoom ) {
							debugLog( 'Calling loadServos( ' + lat + ', ' + lon + ', ' + (zoom-1) + ' ) due to insufficient results' );
							loadServos( lat, lon, zoom-1 );
							return;
						}

						// Have some servos, either searching largest area possible, or found desired number of servos

						// Get distances
						debugLog( 'Calculating distances' );
						for( i in servos.ResultData.Data ) {
							var difflat = ( lat - servos.ResultData.Data[i].Latitude ) * Math.PI / 180;
							var difflon = ( lon - servos.ResultData.Data[i].Longitude ) * Math.PI / 180;
							var a = Math.sin( difflat / 2 ) * Math.sin( difflat / 2 ) + Math.cos( servos.ResultData.Data[i].Latitude * Math.PI / 180 ) * Math.cos( lat * Math.PI / 180 ) * Math.sin( difflon / 2 ) * Math.sin( difflon / 2 );
							var c = 2 * Math.atan2( Math.sqrt( a ), Math.sqrt( 1 - a ) );
							servos.ResultData.Data[i].Distance = 6371 * c; // 6371 is approx radius of earth
						}

						if(!isHome())
						{
							displayMap(lat,lon,zoom-2);
							updateMappletLink(lat,lon,zoom);
						}

						// Output results
						servoHash = servos.ResultData.Data;
						servoCheapest = servoHash[0].Price;
						outputServos();
					});

				} else {
					debugLog( 'Failed Lat: ' + loadServos_lat + ', Lon: ' + loadServos_lon + ', Fuel: ' + loadServos_fueltype + ', Brand: ' + loadServos_fuelbrand + ', Zoom: ' + loadServos_zoom );
				}
			}

			function sortByPrice() {
				if( servoSortOrder != 'price' ) {
					servoSortOrder = 'price';
					outputServos();
				}
				_gel('sortByPriceLink').className = 'current';
				_gel('sortByLocationLink').className = '';
			}

			function sortByLocation() {
				if( servoSortOrder != 'location' ) {
					servoSortOrder = 'location';
					outputServos();
				}
				_gel('sortByPriceLink').className = '';
				_gel('sortByLocationLink').className = 'current';
			}

			// Search Functions
			function searchByAddress() {
				if ( _gel( 'address' ).value == '' ) return;
				var address = _gel( 'address' ).value + ', Australia';
				prefs.set('address', _gel( 'address' ).value);
				search( address );
			}

			function search( address ) {
				var geocoder = new GClientGeocoder();
				geocoder.getLocations( address, processPlacemarks );
			}

			// Helper Functions

			function clearOptions(select) {
				var elSel = select;
				var i;
				for (i = elSel.length - 1; i>=0; i--) {
					elSel.remove(i);
				}
			}

			function addOption(select, text, value, selected) {
				var elOptNew = document.createElement('option');
				elOptNew.text = text;
				elOptNew.value = value;
				elOptNew.selected = selected;
				var elSel = select;

				try {
					elSel.add(elOptNew, null); // standards compliant; doesn't work in IE
				}
					catch(ex) {
					elSel.add(elOptNew); // IE only
				}
			}

			function updateComboBox( response, responseTextKey, responseValueKey, elementId, defaultValue, addAllOption, allOptionName ) {
				if( response == '' ) return false;

				var responseJson = '';
				eval('responseJson = '+response);

				var comboEl = _gel(elementId);

				// update combo box with selected fuels
				if(responseJson.ResultData.ResultCode == '0') {
					var data = responseJson.ResultData.Data
					clearOptions(comboEl);
					if( addAllOption ) {
						addOption(comboEl, '-All '+allOptionName+'-', '-All '+allOptionName+'-', false);
					}
					for(var i=0; i<data.length; i++) {
						var text = data[i][responseTextKey];
						var value = data[i][responseValueKey];
						var selected = (value == defaultValue);
						addOption(comboEl, text, value, selected);
					}

					// enable combo again
					comboEl.disabled = false;
				} else {
					debugLog( 'Error retrieving data for ' + elementId);
				}
			}

			function handleKeyUp( element, event ) {

				prefs.set('fueltype', _gel( 'fueltype' ).value);
				prefs.set('fuelbrand', _gel( 'fuelbrand' ).value);

				switch( element.id ) {
					case 'fueltype':
						// If there are already search results
						if( servoHash.length > 0 ) {
							_gel('resultspanel').innerHTML = '<p>Loading...</p>';
							_IG_AdjustIFrameHeight();
							loadFuelBrands();
							loadServos( loadServos_lat, loadServos_lon, loadServos_maxZoom );
						} else {
							loadFuelBrands();
						}
						break;

					case 'fuelbrand':
						if( servoHash.length > 0 ) {
							_gel('resultspanel').innerHTML = '<p>Loading...</p>';
							_IG_AdjustIFrameHeight();
							loadServos( loadServos_lat, loadServos_lon, loadServos_maxZoom );
						}
						break;

					case 'address':
						if( ( event.keyode || event.which ) == 13 ) {
							_gel('resultspanel').innerHTML = '<p>Loading...</p>';
							_IG_AdjustIFrameHeight();
							searchByAddress();
						}
						break;
				}

			}

			function processPlacemarks( response ) {
				if( response.Status.code != '200' ) {
					return;
				}

				// If only one response
				if( response.Placemark.length == 1 ) {
					var lon = response.Placemark[0].Point.coordinates[0];
					var lat = response.Placemark[0].Point.coordinates[1];
					loadServos( lat, lon, loadServos_maxZoom );
				} else {
					_gel('resultspanel').innerHTML = '<p>&ldquo;' + response.name.replace( /, Australia$/, '' ) + '&rdquo; could not be found</p>';
					_IG_AdjustIFrameHeight();
				}
			}

			function outputServos() {

				//updateOpenInGoogleMapsLink();

				// Count servos to determine pin number
				var servoCounter = 0;

				// Track lowest price to determine pin colour
				var lowestprice = 0;

				// Sort servos
				var sortedServos = servoHash;
				if( servoSortOrder == 'price' ) {
					sortedServos.sort( function( a, b ) {
						return a.Price - b.Price
					});
				}
				if( servoSortOrder == 'location' ) {
					sortedServos.sort( function( a, b ) {
						return a.Distance - b.Distance;
					});
				}

				// Loop through servos
				var servoPtr = 0;
				resultshtml = '';
				while( servoPtr < sortedServos.length ) {
					var servo = sortedServos[servoPtr];

					if( servo.Latitude != "" && servo.Longitude != "" ) {

						//servoHash[servoCounter] = new Array();
						if(!isHome()) {
							placeMarker(servo, servoCounter, ((servoCheapest == servo.Price) ? true : false));
							resultshtml += '<a href="" onclick="showInfoWindowFromLink('+ servoCounter +'); return false;"><p id="pin' + servoCounter + '"' + ( servoCheapest == servo.Price ? ' class="cheapest"' : '' ) + '><span class="price">$'+(parseInt(servo.Price)/1000)+':</span> <span class="name">'+servo.SiteName+'</span> - <span class="timestamp">'+servo.RecordedTime.replace( /^([a-zA-Z]{3}) +([0-9]{1,2}) +2[0-9]{3} +([0-9:APM]+)$/, '$2 $1 at $3' ) +'</span><br/>'+servo.SiteAddress+'<br/>'+servo.SiteSuburb+' '+servo.SitePostcode+'<br/>Distance: ' + ( Math.round( servo.Distance * 100 ) / 100 ) + 'km</p></a>';
						}
						else
						{
							resultshtml += '<a href="" onclick="loadInfoWindowInMap('+ servoCounter +'); return false;"><p id="pin' + servoCounter + '"' + ( servoCheapest == servo.Price ? ' class="cheapest"' : '' ) + '><span class="price">$'+(parseInt(servo.Price)/1000)+':</span> <span class="name">'+servo.SiteName+'</span> - <span class="timestamp">'+servo.RecordedTime.replace( /^([a-zA-Z]{3}) +([0-9]{1,2}) +2[0-9]{3} +([0-9:APM]+)$/, '$2 $1 at $3' ) +'</span><br/>'+servo.SiteAddress+'<br/>'+servo.SiteSuburb+' '+servo.SitePostcode+'<br/>Distance: ' + ( Math.round( servo.Distance * 100 ) / 100 ) + 'km</p></a>';
						}

						++servoCounter;
					}

					++servoPtr;
				}

				if( servoPtr > 0 ) {
					resultshtml = resultshtml + '<div id="clearresults" class="clearresultsclass"><p><a href="#" onclick="clearResults(); return false;">Clear results</a></p></div>';
				}

				_gel('resultspanel').innerHTML=resultshtml;
				openInfoMarker();
				_IG_AdjustIFrameHeight();
			}

			// This function opens the infoWindow for the marker (if) clicked in the home view.
			function openInfoMarker()
			{
				if( autoOpened ) return;

				var homePrefs = gadgets.views.getParams();
				servoId = homePrefs["servoId"];
				autoOpen = homePrefs["autoOpen"];

				if(autoOpen)
				{
					showInfoWindowFromLink(servoId);
					autoOpened = true;
				}
			}

			function clearResults() {

				loadServos_lat=0;

				prefs.set( 'fueltype' , '' );
				prefs.set( 'fuelbrand' , '' );
				prefs.set( 'address' , '' );

				_gel( 'fueltype' ).value = 2;
				_gel( 'fuelbrand' ).value = '-All Brands-';
				_gel( 'address' ).value = '';
				_gel( 'resultspanel' ).innerHTML='';
				_IG_AdjustIFrameHeight();

				if(!isHome())
				{
					displayMap(-29, 135, 4);
					updateMappletLink(-29, 135, 4);
				}
			}

			function getMarkerInfoWindowFunction( marker, servo ) {
				return function() {
					var fueltypeEl = _gel('fueltype');

					_IG_FetchContent( serviceUrl + 'op=SiteWeeklyPriceHistory&SiteID=' + servo.SiteID + '&FuelType=' + fueltypeEl.value, function(response) {

						if( response == '' ) return false;

						var historicalData = '';
						eval('historicalData = ' + response);

						var tabs = Array();

						// info HTML
						var infoHtml = '<div style="' + tabStyle + '">';

						infoHtml += '<table border="0" cellpadding="0" cellspacing="0"><tr><td>';
						infoHtml += '<span style="' + tabHeadingStyle + '">$' + (parseInt(servo.Price)/1000) + '</span> - <strong>' + servo.SiteName + '</strong>';
						infoHtml += '</td><td align="right">';
						infoHtml += '<img src="' + servo.BrandLogo + '" alt="logo: ' + servo.SiteName + '" style="padding: 0 10px;"/>';
						infoHtml += '</td></tr></table>';

						infoHtml += '<p>' + servo.SiteAddress + ', ' + servo.SiteSuburb + ' ' + servo.SitePostcode + '</p>';

						if( servo.RecordedTime != '' ) infoHtml += '<p><span style="font-size:90%">Last updated on ' + servo.RecordedTime + '</span></p>';

						infoHtml += '<p><a href="http://motormouth.com.au/registration.aspx" target="_blank">Setup email alerts with MotorMouth</a></p>';

						infoHtml += '</div>'; //end cond_tab

						tabs[0] = new GInfoWindowTab( 'Info', infoHtml );

						// trends HTML
						var trendsHtml = '<div style="'+tabStyle+'"><span style="'+tabHeadingStyle+'">'+servo.SiteName+'</span><br />';
						if(historicalData.ResultData.ResultCode == '0') {
							trendsHtml += '<img src="' + getTrendsGoogleChartUri( historicalData.ResultData.Data, 220, 110 ) + '" />';
						} else {
							trendsHtml += 'Historical data is not currently available.';
						}
						trendsHtml += '</div>';
						tabs[1] = new GInfoWindowTab( 'Trends', trendsHtml );

						marker.openInfoWindowTabsHtml(tabs);

					});
				}
			}

			function getTrendsGoogleChartUri( historicalData, width, height ) {

				// History passed in reverse chronological order - reverse this
				var tmp = historicalData;
				historicalData = new Array();
				for( var i = tmp.length-1; i >=0; --i ) {
					historicalData[historicalData.length] = tmp[i];
				}

				// Find max and min
				var max = 0;
				var min = 999999999;
				for( idx in historicalData ) {
					max = Math.max( max, historicalData[idx].Price );
					min = Math.min( min, historicalData[idx].Price );
				}

				// Round max up and min down to nearest 20c
				max = Math.ceil( max/20 ) * 20;
				min = Math.floor( min/20 ) * 20;
				var diff = max - min;

				// Determine increments for values
				// Google Charts' simple encoding supports 62 values: A-Za-z0-9 = 0..61
				var encodeString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
				var step = 61/diff;

				// Generate list of values and x-axis labels
				var values = '';
				var xaxis1 = '';
				var xaxis2 = '';
				var monthnames = new Array('','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
				for( idx in historicalData ) {
					var price = historicalData[idx].Price;
					values += encodeString.charAt( Math.round( ( price - min ) * step ) );
					xaxis1 += '|' + historicalData[idx].DayOfWeek.substring(0,3);
					var date = historicalData[idx].DayDate.replace( / 20[0-9]{2}$/, '').split( ' ' );
					var dayofmonth = date[0].replace( /^0/, '' );
					for( var month = 1; monthnames[month] != date[1]; ++month ) {}
					xaxis2 += '|' + dayofmonth + '/' + month;
				}

				// Generate Y-axis labels
				var yaxis = '';
				var yaxis_show = true;
				for( var value = min; value <= max; value += 10 ) {
					yaxis += '|';
					// only show every other value
					if( yaxis_show ) {
						var valStr = ( value / 1000 ) + '';
						while( valStr.length < 4 ) valStr += '0';
						yaxis += '$' + valStr;
					}
					yaxis_show = !yaxis_show;
				}

				var uri = 'http://chart.apis.google.com/chart?cht=lc&chco=0000ff&chg=100,20&chs=' + width + 'x' + height + '&chd=s:' + values + '&chxt=x,x,y&chxl=0:' + xaxis1 + '|1:' + xaxis2 + '|2:' + yaxis;
				return uri;
			}

			function showInfoWindowFromLink( i ) {
				GEvent.trigger( servoHash[i].marker, "click" );
			}

			function updateOpenInGoogleMapsLink() {
				if( loadServos_lat != 0 ) {
					var fueltype = _gel('fueltype').value;
					var fuelbrand = _gel('fuelbrand').value;
					// There's something fishy in the logic somewhere, but the zoom levels used in this gadget don't match the zoom levels
					// in Google Maps. The gadet results match, approximately, the map at 2 zoom levels down on a 1024x768 screen.
					var mapUrl = 'http://maps.google.com/maps/mpl?moduleurl=http://petrolpricetracker.googlecode.com/svn/trunk/mapplet/motormouth.xml&ll=' + loadServos_lat + ',' + loadServos_lon + '&z=13';
					_gel( 'mapview_link' ).innerHTML = '<a href="' + mapUrl + '" target="_blank" onclick="window.open(this.href);return false;">Map View &raquo;</a>';
				} else {
					_gel( 'mapview_link' ).innerHTML = 'Map View &raquo;';
				}
			}

			function wordwrap( str, int_width, str_break, cut ) {
				// http://kevin.vanzonneveld.net
				// +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
				// +   improved by: Nick Callen
				// +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
				// *     example 1: wordwrap('Kevin van Zonneveld', 6, '|', true);
				// *     returns 1: 'Kevin |van |Zonnev|eld'

				var m = int_width, b = str_break, c = cut;
				var i, j, l, s, r;

				if(m < 1) {
					return str;
				}
				for(i = -1, l = (r = str.split("\n")).length; ++i < l; r[i] += s) {
					for(s = r[i], r[i] = ""; s.length > m; r[i] += s.slice(0, j) + ((s = s.slice(j)).length ? b : "")){
						j = c == 2 || (j = s.slice(0, m + 1).match(/\S*(\s)?$/))[1] ? m : j.input.length - j[0].length || c == 1 && m || j.input.length + (j = s.slice(m).match(/^\S*/)).input.length;
					}
				}

				return r.join("\n");
			}

			function debugLog( obj ) {
				//console.log( obj );
			}

			function getViewName() {
				return gadgets.views.getCurrentView().getName();
			}

			function displayMap(lat, lon, zoom) {
				if (GBrowserIsCompatible()) {
					mapObj = new GMap2(document.getElementById("canvas"));
					mapObj.setCenter(new GLatLng(lat, lon), zoom);
					mapObj.addControl(new GLargeMapControl());
					mapObj.addControl(new GMapTypeControl());
					GEvent.addListener( mapObj, 'moveend', handleMapUpdate );
				}
			}

			var handleMapUpdate_right;
			var handleMapUpdate_top;
			var handleMapUpdate_left;
			var handleMapUpdate_bottom;
			var handleMapUpdate_fuelbrand;
			var handleMapUpdate_fueltype;
			function handleMapUpdate() {

				if( !moveListenerActive ) return;

				var mapBounds = mapObj.getBounds();
				var sw = mapBounds.getSouthWest();
				var ne = mapBounds.getNorthEast();
				var current_right = ne.lng();
				var current_top = ne.lat();
				var current_left = sw.lng();
				var current_bottom = sw.lat();

				var mapCenter = mapObj.getCenter();
				var lat = mapCenter.lat();
				var lon = mapCenter.lng();
				var zoom = mapObj.getZoom();

				var fueltypeEl = _gel('fueltype');
				var fueltype = fueltypeEl.value;

				var brandEl = _gel('fuelbrand');
				var fuelbrand = escape( brandEl.value == '-All Brands-' ? 'All Brands' : brandEl.value );

				if( handleMapUpdate_right != current_right || handleMapUpdate_top != current_top || handleMapUpdate_left != current_left || handleMapUpdate_bottom != current_bottom || handleMapUpdate_fueltype != fueltype || handleMapUpdate_fuelbrand != fuelbrand ) {
					handleMapUpdate_right = current_right;
					handleMapUpdate_top = current_top;
					handleMapUpdate_left = current_left;
					handleMapUpdate_bottom = current_bottom;
					handleMapUpdate_fueltype = fueltype;
					handleMapUpdate_fuelbrand = fuelbrand;

					debugLog( 'Map moved' );

					_gel('resultspanel').innerHTML = '<p>Loading...</p>';
					_IG_AdjustIFrameHeight();

					// add padding to lookup
					var hpad = Math.abs( current_right - current_left ) * 0.05;
					var vpad = Math.abs( current_bottom - current_top ) * 0.05;

					current_left += hpad;
					current_right -= hpad;
					current_top -= vpad;
					current_bottom += vpad;

					_IG_FetchContent( serviceUrl + 'op=BrandGeocodeSearch&Brand=' + fuelbrand + '&FuelType=' + fueltype + '&TopLatitude=' + current_top + '&LeftLongitude=' + current_left + '&BottomLatitude=' + current_bottom + '&RightLongitude=' + current_right, function( response ) {

						debugLog( 'Received result from MotorMouth' );

						// Errors?
						if( response == '' ) {
							debugLog( 'blank response' );
							return false;
						}

						if( response.length > 90000 ) {
							_gel('resultspanel').innerHTML = '<p>Too many results found. Please zoom in or refine your search criteria.</p>';
							_IG_AdjustIFrameHeight();
							return false;
						}

						var servos;
						eval( 'servos = ' + response );

						// No results?
						if( servos.ResultData.ResultCode != '0' || ( servos.ResultData.Data && servos.ResultData.Data.length == 0 ) ) {
							_gel('resultspanel').innerHTML = '<p>No results found.</p>';
							_IG_AdjustIFrameHeight();
							return false;
						}

						debugLog( "Got " + servos.ResultData.Data.length + " servos" );

						// Have some servos, either searching largest area possible, or found desired number of servos

						// Get distances
						debugLog( 'Calculating distances' );
						for( i in servos.ResultData.Data ) {
							var difflat = ( lat - servos.ResultData.Data[i].Latitude ) * Math.PI / 180;
							var difflon = ( lon - servos.ResultData.Data[i].Longitude ) * Math.PI / 180;
							var a = Math.sin( difflat / 2 ) * Math.sin( difflat / 2 ) + Math.cos( servos.ResultData.Data[i].Latitude * Math.PI / 180 ) * Math.cos( lat * Math.PI / 180 ) * Math.sin( difflon / 2 ) * Math.sin( difflon / 2 );
							var c = 2 * Math.atan2( Math.sqrt( a ), Math.sqrt( 1 - a ) );
							servos.ResultData.Data[i].Distance = 6371 * c; // 6371 is approx radius of earth
						}

						if(!isHome())
						{
							displayMap(lat,lon,zoom);
							updateMappletLink(lat,lon,zoom);
						}

						// Output results
						servoHash = servos.ResultData.Data;
						servoCheapest = servoHash[0].Price;
						outputServos();
					});
				}
			}

			function placeMarker(servo, counter, lowestprice)
			{
				var pumpLetters = 'abcdefghijklmnopqrstuvwxyz';

				var pumpLetter = pumpLetters.charAt(counter);

				if( lowestprice == true) {
					var pumpImg = '__UP_markerimgcheap__' + pumpLetter + '.gif';
				} else {
					var pumpImg = '__UP_markerimg__' + pumpLetter + '.gif';
				}

				var cachedPinImage = _IG_GetImage(pumpImg, { refreshInterval: (60 * 60 * 24) }); // cache image for 24 hours

				var pumpIcon = new GIcon();
				pumpIcon.image = cachedPinImage.src;
				pumpIcon.iconSize = new GSize(20, 34);
				pumpIcon.iconAnchor = new GPoint(9, 33);
				pumpIcon.infoWindowAnchor = new GPoint(9, 36);
				var pumpMarkerOptions = { icon:pumpIcon };

				var point = new GLatLng(servo.Latitude, servo.Longitude);
				var marker = new GMarker(point, pumpMarkerOptions);
				GEvent.addListener(marker, "click", getMarkerInfoWindowFunction(marker, servo));
				GEvent.addListener(marker, "infowindowopen", function() { moveListenerActive = false; });
				GEvent.addListener(marker, "infowindowclose", function() { moveListenerActive = true; });
				servoHash[counter].marker = marker;
				mapObj.addOverlay(marker);

			}

			// This function is to switch to map view and opening up info window for selected servo.
			function loadInfoWindowInMap(id) {
				var supported_views = gadgets.views.getSupportedViews();
				var params = { servoId : id, autoOpen : true };
				gadgets.views.requestNavigateTo(supported_views['canvas'], params);
			}

			function navigateTo(dest) {
				var supported_views = gadgets.views.getSupportedViews();
				gadgets.views.requestNavigateTo(supported_views[dest]);
			}

			function setMapViewLink()
			{
				if( isHome() ) {
					_gel('viewoptions').innerHTML = '<img src="__UP_imglocation__map_view.png" /> <a href="" onclick="navigateTo(\'canvas\'); return false;">Map View &raquo;</a>';
				} else {
					_gel('viewoptions').innerHTML = '<a href="" id="viewTheMappletAnchor" target="_blank">View on Google Maps</a>';
				}
			}

			function updateMappletLink(lat,lon,zoom)
			{
				_gel('viewTheMappletAnchor').href = "http://maps.google.com/maps/mpl?moduleurl=http://petrolpricetracker.googlecode.com/svn/trunk/mapplet/motormouth.xml&ll="+ lat +","+ lon +"&z=13";
			}

		</script>

		<script type="text/javascript">
		var gaJsHost = (("https:" == document.location.protocol) ?
		"https://ssl." : "http://www.");
		document.write(unescape("%3Cscript src='" + gaJsHost +	"google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
		</script>
		<script type="text/javascript">
		var pageTracker = _gat._getTracker("UA-6194838-1");
		pageTracker._trackPageview();
		</script>